﻿using System;
using System.Collections.Generic;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using SimpleServiceBus.Bus;
using SimpleServiceBus.Bus.MessageManagement.MessageHandling;
using SimpleServiceBus.Bus.Pipeline;

namespace SimpleServiceBus.Tests.Bus.MessageManagement.MessageHandling
{
    [TestFixture]
    public class DefaultMessageHandlerResolutionServiceTestFixture
    {
       

        [Test]
        public void Bindings_Are_Properly_Cached()
        {
            var svc = new TestableResolutionService();
            svc.RegisterMessageHandler(typeof (MultiMsgHandler));

            IMessageHandler[] results = svc.ResolveHandlersFor(new MessageEnvelope {Body = new Message_A()});
            svc.ResolveHandlersFor(new MessageEnvelope {Body = new Message_B()});
            svc.ResolveHandlersFor(new MessageEnvelope {Body = new AllFamilies()});

            Assert.That(svc.PublicCache.Count, Is.EqualTo(3));
            Assert.That(svc.PublicCache[typeof (Message_A)].Length, Is.EqualTo(2));

            IMessageHandler[] results2 = svc.ResolveHandlersFor(new MessageEnvelope {Body = new Message_A()});

            Assert.That(results, Is.EqualTo(results2));
        }

        [Test]
        public void Can_Register_Multi_Message_Handler_And_Retrieve_Correct_Bindings()
        {
            var svc = new TestableResolutionService();
            svc.RegisterMessageHandler(typeof (MultiMsgHandler));

            IMessageHandler[] results = svc.ResolveHandlersFor(new MessageEnvelope {Body = new Message_A()});
            Assert.That(results.Length, Is.EqualTo(2));

            results = svc.ResolveHandlersFor(new MessageEnvelope {Body = new Message_B()});
            Assert.That(results.Length, Is.EqualTo(1));

            results = svc.ResolveHandlersFor(new MessageEnvelope {Body = new AllFamilies()});
            Assert.That(results.Length, Is.EqualTo(2));

            Assert.That(svc.PublicBindings.Count, Is.EqualTo(4));
        }

        public class MultiMsgHandler : IMessageHandler<IMessageFamily_A>,
                                      IMessageHandler<Message_A>,
                                      IMessageHandler<Message_B>,
                                      IMessageHandler<AllFamilies>
        {
            #region IMessageHandler<AllFamilies> Members

            public void Handle(AllFamilies message, IMessageContext context)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IMessageHandler<IMessageFamily_A> Members

            public void Handle(IMessageFamily_A message, IMessageContext context)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IMessageHandler<Message_A> Members

            public void Handle(Message_A message, IMessageContext context)
            {
                throw new NotImplementedException();
            }

            #endregion

            #region IMessageHandler<Message_B> Members

            public void Handle(Message_B message, IMessageContext context)
            {
                throw new NotImplementedException();
            }

            #endregion
        }

        public class TestableResolutionService : DefaultMessageHandlerResolutionService
        {
            public List<IMessageHandlerBinding> PublicBindings
            {
                get { return MessageHandlerBindings; }
            }

            public Dictionary<Type, IMessageHandler[]> PublicCache
            {
                get { return HandlerCache; }
            }
        }
    }
}